/*
* This file is a part of the open-eBackup project.
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
* If a copy of the MPL was not distributed with this file, You can obtain one at
* http://mozilla.org/MPL/2.0/.
*
* Copyright (c) [2024] Huawei Technologies Co.,Ltd.
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*/
#ifndef NAS_REPLICATION_SERVICE_H
#define NAS_REPLICATION_SERVICE_H
#include <string>
#include <cstdint>
#include "error.h"
#include "device_access/dorado/DoradoNas.h"
#include "nas_share/common/HetroCommonService.h"
#include "device_access/dorado/DoradoBlock.h"
#include "device_access/ControlDevice.h"
#include "constant/PluginServiceCommon.h"
#include "ReplicationDeviceManager.h"

namespace NasRepServiceObjOp {

enum class NasReplicationServiceErrorCode {
    ReplicationServiceNormal,
    ReplicationServiceAbNormal,
    ReplicationDeviceFault
};

class NasReplicationService {
public:
    NasReplicationService(const std::string& productFSID, const std::string& basicFSID, const uint64_t& qos);
    ~NasReplicationService();
    uint64_t m_qos = 0;
    std::string m_productFSID = "";
    std::string m_basicFSID = "";
    std::string m_pairID = "";
    bool m_isExistPairValid = false;
    std::string m_remoteDeviceID = "";
    static std::unique_ptr<NasReplicationService> GetReplicationInstance(
        const std::string& productFSID, const std::string& basicFSID, const uint64_t& qos);
    NasReplicationServiceErrorCode PrepareRemoteReplicatonPair(std::shared_ptr<Module::DoradoNas>& localController,
        std::shared_ptr<Module::DoradoNas>& productController);
    bool RelinkRemoteDevice(std::shared_ptr<Module::DoradoNas>& productController);
    bool RecoverRemoteDeviceLink(std::shared_ptr<Module::DoradoNas>& basicController,
        std::shared_ptr<Module::DoradoNas>& productController, int healthStatus);
    bool CreateReplicationPair(std::shared_ptr<Module::DoradoNas>& deviceController, const int& localResId,
        const std::string& remoteDevId, int& remoteResId, std::string &pairID);
    void SetExistPairValid(bool validFlag);
    bool IsExistPairValid();
    bool UpdateReplicationPairBandWidth(std::shared_ptr<Module::DoradoNas>& deviceController,
        const std::string& pairID);
    bool ActiveReplicationPair(std::shared_ptr<Module::DoradoNas>& localController, const std::string& pairID,
        int64_t& errorCode);
    bool SplitReplicationPair(std::shared_ptr<Module::DoradoNas>& deviceController, const std::string& pairID);
    bool DeleteReplicatonPair(std::shared_ptr<Module::DoradoNas>& deviceController, const std::string& pairID);
    bool SwitchOverPrimaryAndSecondResource(std::shared_ptr<Module::DoradoNas>& deviceController,
        const std::string& pairID);
    bool GetPairInfoByID(std::shared_ptr<Module::DoradoNas>& deviceController, const std::string& pairID,
        Module::ReplicationPairInfo& replicationPairInfo);
    bool OpenPerformanceStatisticSwitch(std::shared_ptr<Module::DoradoNas>& deviceController);
    void GetReplicationSpeed(std::shared_ptr<Module::DoradoNas>& deviceController, const std::string& pairID,
        uint64_t& speed);
    bool CreateSnapShotInStorage(std::shared_ptr<Module::DoradoNas>& deviceController,
        const std::string& snapshotname, std::string& snapshotID);
    bool DeleteSnapShotInStorage(std::shared_ptr<Module::DoradoNas>& deviceController, const std::string& snapshotName);
    bool RevertSnapShotInStorage(std::shared_ptr<Module::DoradoNas>& deviceController, const std::string& snapshotName,
        const std::string &snapshotId, int64_t &errorCode);
    int QueryRevertEndInfoInStorage(std::shared_ptr<Module::DoradoNas>& deviceController,
        std::string& rollbackRate, std::string& rollbackStatus, std::string& endTime, std::string& snapshotId);
    bool QueryRevertInfoInStorage(std::shared_ptr<Module::DoradoNas>& deviceController,
        std::string& rollbackRate, std::string& rollbackStatus, int64_t &errorCode);
    bool CreateFileSystemInRemoteDevice(std::shared_ptr<Module::DoradoNas>& localController,
        std::shared_ptr<Module::DoradoNas>& remoteController);
    void DeleteFileSystemInRemoteDevice(std::shared_ptr<Module::DoradoNas>& deviceController);
    void GetPairID(std::string &pairID)
    {
        pairID = m_pairID;
    }
    bool GetPairInfoInProduct(std::shared_ptr<Module::DoradoNas>& productController,
        std::shared_ptr<Module::DoradoNas>& basicController, std::string& pairID);
    bool SecondaryResourceProtectEnable(std::shared_ptr<Module::DoradoNas>& deviceController,
        const std::string& pairID);
    bool SecondaryResourceProtectDisable(std::shared_ptr<Module::DoradoNas>& deviceController,
        const std::string& pairID);
    void SetTaskID(const std::string& mainTaskId);
    void SetProduckIscsiList(const std::vector<std::string>& repPortNameList);

private:
    std::vector<std::string> m_productIscsiList = {};
    std::vector<std::string> m_basicIscsiList = {};
    std::vector<std::string> m_basicIscsiIpList = {};
    std::string m_remoteDeviceUserName = "";
    std::string m_remoteDeviceUserPassword = "";
    bool CreateRemoteDeviceAdministrator(std::shared_ptr<Module::DoradoNas>& basicController);
    bool CreateRemoteDevice(std::shared_ptr<Module::DoradoNas>& productController);
    bool CreateRemoteDeviceTaskInner(std::shared_ptr<Module::DoradoNas>& basicController,
        std::shared_ptr<Module::DoradoNas>& productController);
    NasReplicationServiceErrorCode CreateRemoteDeviceAndBindRepPortGroups(std::shared_ptr<Module::DoradoNas>& basicController,
        std::shared_ptr<Module::DoradoNas>& productController);
    bool AddLocalAndRemotePort(std::shared_ptr<Module::DoradoNas>& productController,
        std::shared_ptr<Module::DoradoNas>& basicController, const std::string& basicDeviceID);
    bool CreateReplicationRepportgroup(std::shared_ptr<Module::DoradoNas>& basicController,
        std::shared_ptr<Module::DoradoNas>& productController, std::string& productGroupID, std::string& basicGroupID);
    bool GetLogicPortNameList(std::shared_ptr<Module::DoradoNas>& productController,
        std::shared_ptr<Module::DoradoNas>& basicController);
    bool CheckReplicatonPairInBaic(std::shared_ptr<Module::DoradoNas>& basicController,
        Module::ReplicationPairInfo replicationPairInfo);
    std::string GeneratePassword();
    bool NameLegalization(std::string &name);
    std::string GeneratePasswordOnce();
    bool GetRemoteDeviceUserPwd(const std::string &deviceUser);
    bool FirstCreateRemoteDeviceInfo(std::shared_ptr<Module::DoradoNas>& basicController,
        std::shared_ptr<Module::DoradoNas>& productController, std::string basicEsn);
    bool CreateRemoteDeviceTask(std::shared_ptr<Module::DoradoNas>& basicController,
        std::shared_ptr<Module::DoradoNas>& productController);
    bool WaitRemoteDeviceNormal(std::shared_ptr<Module::DoradoNas>& productController, std::string basicEsn);

    std::string m_mainTaskId;
};
} // namespace NasRepServiceObjOp
#endif
